/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package project1;

import java.util.HashMap;

/**
 *
 * @author rr
 */
public class CandidateSolution {
    
    int[] tempAssignments;
    boolean[][] possibleAssignments;
    int n=SetUp.getInstance().getLengthOfSchedule()*SetUp.getInstance().getNumberOfEmployees();

    private int numberOfAssignedValues=0;
    
    private int nextVariableIndex;
    private int minimumDomainSize;
    
    public CandidateSolution(int[] tempAssignments, boolean[][] possibleAssignments) {
        this.tempAssignments = tempAssignments;
        this.possibleAssignments = possibleAssignments;
    }
    
    
    public CandidateSolution assignNext(int valueIndex, ConstraintChecker cc){
        
        int newAssignments[] = new int[n];
        boolean[][] newPossibleAssignments = new boolean[possibleAssignments.length][possibleAssignments[0].length];
        
        System.arraycopy(tempAssignments, 0, newAssignments, 0, n);
        
        for(int i=0; i<possibleAssignments.length; ++i){ 
            for(int j=0; j<possibleAssignments[0].length; ++j){ 
                newPossibleAssignments[i][j] = possibleAssignments[i][j];
            }
        }

        newAssignments[this.nextVariableIndex]=valueIndex;
        
        for(int j=0; j<possibleAssignments.length; ++j){ 
                newPossibleAssignments[j][nextVariableIndex] = false;
        }
        
        int[] result= cc.updatePossibleAssignments(newPossibleAssignments, newAssignments);
        int newNextVariableIndex = result==null?-1:result[0];
        int newMinimumDomainSize=result==null?-1:result[1];
        
        CandidateSolution newSolution = new CandidateSolution(newAssignments, newPossibleAssignments);
        
        newSolution.setNumberOfAssignedValues(this.numberOfAssignedValues+1);
        newSolution.setNextVariableIndex(newNextVariableIndex);
        newSolution.setMinimumDomainSize(newMinimumDomainSize);
        return newSolution;
    }
    
    public CandidateSolution assignNext(int valueIndex){
        
        int newAssignments[] = new int[n];
        boolean[][] newPossibleAssignments = new boolean[possibleAssignments.length][possibleAssignments[0].length];
        
        System.arraycopy(tempAssignments, 0, newAssignments, 0, n);
        
        for(int i=0; i<possibleAssignments.length; ++i){ 
            for(int j=0; j<possibleAssignments[0].length; ++j){ 
                newPossibleAssignments[i][j] = possibleAssignments[i][j];
            }
        }

        newAssignments[this.nextVariableIndex]=valueIndex;
        
        for(int j=0; j<possibleAssignments.length; ++j){ 
                newPossibleAssignments[j][nextVariableIndex] = false;
        }
        
        int[] result=ConstraintChecker.getInstance().updatePossibleAssignments(newPossibleAssignments, newAssignments);
        int newNextVariableIndex = result==null?-1:result[0];
        int newMinimumDomainSize=result==null?-1:result[1];
        
        CandidateSolution newSolution = new CandidateSolution(newAssignments, newPossibleAssignments);
        
        newSolution.setNumberOfAssignedValues(this.numberOfAssignedValues+1);
        newSolution.setNextVariableIndex(newNextVariableIndex);
        newSolution.setMinimumDomainSize(newMinimumDomainSize);
        return newSolution;
    }

    
    public CandidateSolution assignNext(int valueIndex, int variableIndex){
        
        int newAssignments[] = new int[n];
        boolean[][] newPossibleAssignments = new boolean[possibleAssignments.length][possibleAssignments[0].length];
        
        System.arraycopy(tempAssignments, 0, newAssignments, 0, n);
        
        for(int i=0; i<possibleAssignments.length; ++i){ 
            for(int j=0; j<possibleAssignments[0].length; ++j){ 
                newPossibleAssignments[i][j] = possibleAssignments[i][j];
            }
        }

        newAssignments[variableIndex]=valueIndex;
        
        for(int j=0; j<possibleAssignments.length; ++j){ 
                newPossibleAssignments[j][variableIndex] = false;
        }
        
        ConstraintChecker.getInstance().updatePossibleAssignments(newPossibleAssignments, newAssignments);
        
        CandidateSolution newSolution = new CandidateSolution(newAssignments, newPossibleAssignments);
        
        newSolution.setNumberOfAssignedValues(this.numberOfAssignedValues+1);
        

        
        return newSolution;
    }

    public int[] getTempAssignments() {
        return tempAssignments;
    }

    public void setTempAssignments(int[] tempAssignments) {
        this.tempAssignments = tempAssignments;
    }

    public boolean[][] getPossibleAssignments() {
        return possibleAssignments;
    }

    public void setPossibleAssignments(boolean[][] possibleAssignments) {
        this.possibleAssignments = possibleAssignments;
    }

    public int getNumberOfAssignedValues() {
        return numberOfAssignedValues;
    }

    public void setNumberOfAssignedValues(int numberOfAssignedValues) {
        this.numberOfAssignedValues = numberOfAssignedValues;
    }

    

    public int getNextVariableIndex() {
        return nextVariableIndex;
    }

    public void setNextVariableIndex(int nextVariableIndex) {
        this.nextVariableIndex = nextVariableIndex;
    }

    public int getMinimumDomainSize() {
        return minimumDomainSize;
    }

    public void setMinimumDomainSize(int minimumDomainSize) {
        this.minimumDomainSize = minimumDomainSize;
    }

    public int getPossibleAssignmentCount() {
        int sum = 0;
        for(int i=0; i<possibleAssignments.length; ++i){ 
            for(int j=0; j<possibleAssignments[0].length; ++j){ 
                if(possibleAssignments[i][j]) ++sum;
            }
        }
        
        return sum;
    }
    
    
    
}
